﻿/*
 * 名称：INI读写类
 * 
 * 作用：实现对INI文件读写的封装，只需要简单的两三个参数即可使用，包括三个主要函数：
 *       public string ReadValue(string lpApplicationName, string lpKeyName)
 *       public bool WriteValue(string lpApplicationName, string lpKeyName, string lpString)
 *       public string ReadValue(string lpApplicationName, string lpKeyName, string lpDefault)
 * 
 * 作者：郝  伟
 * 
 * 时间：2010-5-5   初步建立这几个方法。   
 *      2011-6-3   添加Section属性，这样就可以直接写值。 
 *      2020/06/30 修改变量名称，使之更加简单易懂，同时添加了两个静态方法Write和Read，在简单应用场景下不需要初始化对象。
 * 
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.IO;
using System.Windows.Forms;

namespace WindGoes6.Data
{
	/// <summary>
	/// 此类用于实现对INI文件的读写，包括了读，写两个方法，同时还有文件位置属性及默认输出属性。
	/// </summary>
	public class IniAccess
	{
		// 注：以下两函数的路径需要使用绝对路径。
		[DllImport("kernel32")]
		private static extern bool GetPrivateProfileString(string lpApplicationName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);
		[DllImport("kernel32")]
		private static extern bool WritePrivateProfileString(string lpApplicationName, string lpKeyName, string lpString, string lpFileName);

		/// <summary>
		/// 读取或设置所操作的INI文件的位置。
		/// </summary>
		public string FilePath = "config.ini";

		/// <summary>
		/// 读取或设置读取失败的信息。
		/// </summary>
		public string DefaultError = "Failed to read.";

		/// <summary>
		/// 默认值，初始化为空
		/// </summary>
		public string DefaultValue = "";

		/// <summary>
		/// 默认的段，初始化为 Application
		/// </summary>
		public string Section = "Application";


		/// <summary>
		/// 此类用于实现对INI文件的读写，包括了读，写两个方法，同时还有文件位置属性及默认输出属性。
		/// </summary>
		public IniAccess() { FilePath = Path.GetFullPath(FilePath); }

		/// <summary>
		/// 此类用于实现对INI文件的读写，包括了读，写两个方法，同时还有文件位置属性及默认输出属性。
		/// </summary>
		/// <param name="path">要操作的INI文件位置，如果不存在会自动创建。</param>
		public IniAccess(string path)
		{
			FilePath = Path.GetFullPath(path);
		}

		/// <summary>
		/// 读取属性的值。
		/// </summary>
		/// <param name="section">字段的类别。</param>
		/// <param name="key">字段名。</param>
		/// <param name="value">要写入的值。</param>
		/// <returns>返回值表示是否执行成功。</returns>
		public bool WriteValue(string section, string key, string value)
		{
			return WritePrivateProfileString(section, key, value, FilePath);
		}

		/// <summary>
		/// 读取属性的值。
		/// </summary>
		/// <param name="key">字段名。</param>
		/// <param name="value">字段值。</param>
		/// <returns>返回值表示是否执行成功。</returns>
		public bool WriteValue(string key, string value)
		{
			return WriteValue(Section, key, value);
		}

		/// <summary>
		/// 读取INI文件中的值。
		/// </summary>
		/// <param name="section">字段的类别。</param>
		/// <param name="key">字段名。</param>
		/// <param name="defaultValue">读取失败的返回值。</param>
		/// <returns>字段值.</returns>
		public string ReadValue(string section, string key, string defaultValue = "")
		{
			StringBuilder sb = new StringBuilder(255);
			GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, FilePath);
			return sb.ToString();
		}

		/// <summary>
		/// 读取INI文件中的值。
		/// </summary> 
		/// <param name="key">字段名。</param>
		/// <returns>字段值。</returns>
		public string ReadValue(string key)
		{
			return ReadValue(Section, key);
		}

		/// <summary>
		/// 将指定的值写到指定的字段，默认段为：Others，默认文件为当前目录下的：config.ini
		/// </summary>
		/// <param name="key">键</param>
		/// <param name="value">值</param>
		/// <param name="section">段</param>
		/// <param name="filepath">保存文件</param>
		/// <returns></returns>
		public static bool Write(string key, string value, string section = "Application", string filepath = "config.ini")
		{
			if (!filepath.Contains(":"))
				filepath = Path.GetFullPath(filepath);
			return WritePrivateProfileString(section, key, value, filepath);
		}

		/// <summary>
		/// 读取指定的值，
		/// </summary>
		/// <param name="key">键</param>
		/// <param name="defaultValue">值</param>
		/// <param name="section">段</param>
		/// <param name="filepath">保存文件</param>
		/// <returns></returns>
		public static string Read(string key, string defaultValue = "", string section = "Application", string filepath = "config.ini")
		{
			StringBuilder sb = new StringBuilder(1024);
			if (!filepath.Contains(":"))
				filepath = Path.GetFullPath(filepath);
			return GetPrivateProfileString(section, key, defaultValue, sb, sb.Capacity, filepath) ? sb.ToString() : defaultValue;
		}
	}
}
